#!/usr/bin/env python
# -*- coding:utf-8 -*-

""" 
@author: zhaoqifa@baidu.com
@license: Copyright (c) 2013 Baidu.com, Inc. All Rights Reserved
"""
import time
from datetime import datetime
from lib.kthread import KThread as KThread

class ThreadPool(object):
    def __init__(self,threads_info = {}):
        #threads_info is a dict: key is the name of thread; You need a name to distinguish return value of threads.
        #value is a list, list[0]->default return value; list[1]->function point; list[2]->function parameters
        self.threads_info = threads_info
        self.ret_info = {}
        self.threads = []
        self.init()
    
    def init(self):
        for tname in self.threads_info:
            self.ret_info[tname] = self.threads_info[tname][0]

            new_arg_list = []
            new_arg_list.append(tname)
            new_arg_list.extend(self.threads_info[tname][1:])

            new_arg_tuple = tuple(new_arg_list)
            t = KThread(target=self.trace_func,name=tname,args=new_arg_tuple)
            t.setDaemon(True)
            self.threads.append(t)

    def trace_func(self, tname, func, *args, **kwargs):
        ret = func(*args, **kwargs)
        self.ret_info[tname] = ret

    def start(self,max_time=None):
        for thread in self.threads:
            thread.start()

        start_time = datetime.now()
        print "start time >>>",start_time
            
        while max_time == None or (datetime.now()-start_time).seconds < max_time:
            time.sleep(0.1)
            exit_thread_num = 0
            for thread in self.threads:
                if not thread.isAlive():
                    exit_thread_num += 1
            if exit_thread_num >= len(self.threads):
                break;

        for thread in self.threads:
            if thread.isAlive():
                self.ret_info[thread.getName()] = "TIMEOUT"
                thread.kill()
        for thread in self.threads:
            thread.join()
        print "end time >>>",str(datetime.now())
        return self.ret_info
        
